﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"Stack.h"
using namespace std;//不建议到项目中展开

//----------------------------------------------------------
//void Fuct(int a , int b, int c = 30)//半缺省这里是从左到右不给值，函数调用传参数那里是从左往右，主要是为了避免歧义
//{
//	cout << "a=" << a << endl;
//	cout << "b=" << b << endl;
//	cout << "c=" << c << endl<<endl;
//}
//
//int main()
//{
//	Fuct(5,60);
//	return 0;
//}
//----------------------------------------------------------
// 缺省参数
//#include"Stack.h"
//int main()
//{
//
//	// 确定知道要插入100个值
//	ST st1;
//	// 初始化直接开好空间，避免扩容，提高效率
//	STInit(&st1, 100);
//	for (int i = 0; i < 100; i++)
//	{
//		STPush(&st1, i);
//	}
//
//	// 不确定要插入多少个值
//	ST st2;
//	STInit(&st2);
//	STPush(&st1, 1);
//	STPush(&st1, 2);
//
//	//STDataType* p1 = (STDataType*)malloc(4 * sizeof(STDataType));
//	//STDataType* p2 = (STDataType*)realloc(p1, 16 * sizeof(STDataType));
//	//cout << p1 << endl;
//	//cout << p2 << endl;//展示每次扩容realloc函数导致的开销
//
//	return 0;
//}

//----------------------------------------------------------
// 函数重载  C++⽀持在同⼀作⽤域中出现同名函数，但是要求这些同名函数的形参不同，可以是参数个数不同或者
// 类型不同。这样C++函数调⽤就表现出了多态⾏为，使⽤更灵活。C语⾔是不⽀持同⼀作⽤域中出现同名函数的。
// 1.参数类型不同(这里的类型不同包括参数的数据类型和函数的返回类型)记住，参数（数据类型或个数）一定要不同，仅靠返回类型的不同是不对的，编译器前期是无法区分的
//void swap(int* a, int* b)
//{
//
//}
//void swap(double* a, double* b)
//{
//
//}
//void swap(char* a, char* b)
//{
//
//}
//int Add(int left, int right)
//{
//	cout << "int Add(int left, int right)" << endl;
//	return left + right;
//}
//double Add(double left, double right)
//{
//	cout << "double Add(double left, double right)" << endl;
//	return left + right;
//}
//// 2.参数数量不同
//void f()
//{
//	cout << "f()" << endl;
//}
//void f(int a)
//{
//	cout << "f(int "<<a<<")" << endl;
//}
//
//// 3.参数类型顺序不同
//void f(int a, char b)
//{
//	cout << "f(int " << a << ", char " << b << ")" << endl;
//}
//
//void f(char a, int b)
//{
//	cout << "f(char " << a << ", int " << b << ")" << endl;
//}
//
// //下面两个函数构成重载
// //f()但是调用时，会报错，存在歧义，编译器不知道调用谁
//void f1()
//{
//	cout << "f()" << endl;
//}
//
//void f1(int a = 10)
//{
//	cout << "f(int a)" << endl;
//}
//
//
////不能通过返回值来区分函数功能，因为调⽤时⽆法区分，因为最开始就只是传参
////void fxx()
////{}
////
////int fxx()
////{
////	return 0;
////}
//
//int main()
//{
//	//int x1 = 1, x2 = 2;
//	//double d1 = 1.1, d2 = 2.2;
//	//swap(&x1, &x2);
//	//swap(&d1, &d2);
//
//	//f1(1);
//	//f1();//出现歧义，可以是本来就空参的，也可以是缺省的
//	f();
//	f(5);
//	f(5, 'x');
//	f('a',10);
//	//fxx();//错的
//
//	return 0;
//}

//----------------------------------------------------------
//引用 相当于取了个小名，大名是你，小名也是你
//int main()
//{
//	int a = 10;
//	int& app = a;
//	app = 1;
//	cout << "app = " << app << '\n';
//	cout << "a = " << a << '\n'<<endl;
//	a++;
//	cout << "app = " << app << endl;
//	cout << "a = " << a << endl;
//
//	cout << "app = " << &app << endl;
//	cout << "a = " << &a << endl;
//}

//int main()
//{
//	int a = 10;
//	int& b = a;
//
//	cout << &a << endl;//10
//	cout << &b << endl;
//
//	b++;
//
//	cout << a << endl;//11
//	cout << b << endl;
//
//	int& c = a;
//	int& d = b;
//
//	cout << &a << endl;
//	cout << &b << endl;
//	cout << &c << endl;
//	cout << &d << endl;
//
//	int x = 20;
//
//	c = x;
//	cout << a << endl;//20
//	cout << b << endl;
//	cout << c << endl;//20
//	cout << d << endl;
//
//	return 0;
//}

//-------------------------------------
//int fuc(int*arr,int i)
//{
//	return arr[i];// 返回的是一个 int 值（拷贝）
//}
//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6 };
//	for (int i = 0; i < 10; i++)
//	{
//		fuc(arr, i) += 1;//因为你只是取出来一个临时拷贝，修改它没意义，也不允许。也可以理解为就是一个值，常量值无法修改，就算修改也不是对数组修改
//	}
//	for (int i = 0; i < 10; i++)
//	{
//		cout << arr[i] << ' ';
//	}
//	return 0;
//}

//int& fuc(int* arr, int i)
//{
//	return arr[i];// 返回的是一个 int 值（拷贝）
//}
//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6 };
//	for (int i = 0; i < 10; i++)
//	{
//		fuc(arr, i) += 1;
//	}
//	for (int i = 0; i < 10; i++)
//	{
//		cout << arr[i] << ' ';
//	}
//	return 0;
//}

//int& fuc(int* arr, int i)
//{
//	return arr[i];// 返回的是一个 int 值（拷贝）
//}
//int main()
//{
//	int* arr = (int*)malloc(10 * sizeof(int));
//	if (arr == NULL)
//	{
//		perror("malloc");
//		exit(1);
//	}
//	for (int i = 0; i < 10; i++)
//	{
//		arr[i] = i+1;
//	}
//
//	for (int i = 0; i < 10; i++)
//	{
//		fuc(arr, i) += 1;
//	}
//
//	for (int i = 0; i < 10; i++)
//	{
//		cout << arr[i] << ' ';
//	}
//	free(arr);
//	arr = NULL;
//	return 0;
//}

//--------------------------------------
//#include<iostream>
//using namespace std;
//int main()
//{
//	int a = 10;
//	// 编译报错：“ra”: 必须初始化引⽤
//	//int& ra;
//	int& b = a;
//	int c = 20;
//	// 这⾥是⼀个赋值
//	b = c;
//	cout << &a << endl;
//	cout << &b << endl;
//	cout << &c << endl;
//	cout << a << endl;
//	cout << b << endl;
//	cout << c << endl;
//	return 0;
//}

//------------------------------------
void swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
//
//// 引用功能1：做函数形参，修改形参影响实参
void swap(int& p1, int& p2)
{
	int tmp = p1;
	p1 = p2;
	p2 = tmp;
}

//
struct A
{
	int a[100];
	int b;
	//...
};
//
void func(struct A* aa)
{}
//
//// 引用功能2：做函数形参，减少拷贝，提高效率
void func(struct A& aa)
{}
//
//void swap(int p1, int p2)//同时与引用的会报错
//{
//	int tmp = p1;
//	p1 = p2;
//	p2 = tmp;
//}
//
//int main()
//{
//	int x = 1, y = 2;
//	swap(&x, &y);
//	swap(x, y);
//
//	struct A a;
//	func(&a);
//	func(a);
//
//	return 0;
//}

//---------------------------------------------------------------
//void swap(int** pp1, int** pp2)
//{
//	int* tmp = *pp1;
//	*pp1 = *pp2;
//	*pp2 = tmp;
//}
//
//void swap(int*& p1, int*& p2)//做函数形参，修改形参影响实参
//{
//	int* tmp = p1;
//	p1 = p2;
//	p2 = tmp;
//}
//
//int main()
//{
//	int x = 1, y = 2;
//	int* px = &x, * py = &y;
//	//int*& rpx = px;
//
//	cout << px << endl;
//	cout << py << endl;
//	//swap(&px, &py);
//	swap(px, py);
//	cout << px << endl;
//	cout << py << endl;
//
//	return 0;
//}

//------------------------------------------------
typedef struct SeqList
{
	int* a;
	int size;
	int capacity;
}SL;

void SLInit(SL& sl, int n = 4)
{
	sl.a = (int*)malloc(n * sizeof(int));
	// ...
	sl.size = 0;
	sl.capacity = n;
}

void SLPushBack(SL& sl, int x)
{
	// ...扩容
	sl.a[sl.size] = x;
	sl.size++;
}

// 引用功能3：引用做返回值类型，修改返回对象
// 引用功能4：引用做返回值类型，减少拷贝，提高效率
int& SLAt(SL& sl, int i)
{
	assert(i < sl.size);
	return sl.a[i];
}

// 这样写是不安全的，因为返回ret的别名是不安全的
// ret是局部对象func结束，ret就销毁的了，返回他的别名本质也一种类似野指针的行为。上面之所以可以这样，是因为数组的内存是动态分配在堆里面的，出了函数栈还是存在的
  int& func()
  {
  	int ret = 0;
  	//...

  	return ret;
  }

int& fxx()
{
	int xxx = 1000;
	//...

	return xxx;
}

#include<vector>

int main()
{

	cout << func() << endl;

	int& x = func();
	cout << x << endl;
	fxx();
	cout << x << endl;

	SL s;
	SLInit(s);
	SLPushBack(s, 1);
	SLPushBack(s, 2);
	SLPushBack(s, 3);
	SLPushBack(s, 4);

	for (int i = 0; i < s.size; i++)
	{
		SLAt(s, i) += 1;
	}

	for (int i = 0; i < s.size; i++)
	{
		cout << SLAt(s, i) << endl;
	}

	vector<int> v = { 1,2,3,4 };
	v[0] = 10;
	for (size_t i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;

	return 0;
}
